﻿using AutoMapper;
using DFGK.IRepository;
using DFGK.IService;
using DFGK_WMS.Common;
using DFGK_WMS.Model.Dto;
using DFGK_WMS.Model.Enum;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.Linq;
using Yitter.IdGenerator;

namespace DFGK.Service
{
    public class PalletService : BaseService, IPalletService
    {
        private readonly IPalletRepository _pallrepository;
        private readonly IInventoryRepository _inventoryrepository;
        private readonly IStackingStorageRepository _stackingstoragerepository;
        private readonly IPutawayOrderRepository _putawayorderrepository;
        private readonly IUnitOfWork _unitOfWork;
        public PalletService(IMapper mapper, IPalletRepository _pallrepository, IInventoryRepository _inventoryrepository, IUnitOfWork unitOfWork, IStackingStorageRepository stackingstoragerepository, IPutawayOrderRepository putawayorderrepository) : base(mapper)
        {
            _unitOfWork = unitOfWork;
            this._pallrepository = _pallrepository;
            this._inventoryrepository = _inventoryrepository;
            _stackingstoragerepository = stackingstoragerepository;
            _putawayorderrepository = putawayorderrepository;
        }
        /// <summary>
        /// 验证输入的托盘数据是否可用
        /// </summary>
        /// <param name="barCode">托盘条码</param>
        /// <param name="type">类型</param>
        /// <param name="message">错误信息</param>
        /// <returns></returns>
        private int GetPalletCodeInt(string barCode,EmPalletType type,out string message)
        {
            message = string.Empty;
            var convertRes = barCode.ToConvert<int>(out int beginCodeInt);
            if (!convertRes || barCode.Length != 4)
            {
                message = "起始条码必须为四位数字！";
                return 0;
            }
            if (Convert.ToInt32(barCode.Substring(0, 1)) != (int)type)
            {
                message = $"{type.GetDescription()}的条码必须为{(int)type}开头的四位数字";
                return 0;
            }
            return beginCodeInt;
        }
        public bool AddPallet(Pallet dto, out string message)
        {
            message = "";
            var beginBarCodeInt = GetPalletCodeInt(dto.PalletBarcode, dto.Type, out message);
            if (beginBarCodeInt == 0)
            {
                return false;
            }
            var sobj = _pallrepository.QueryIsEntityWhere(x => x.PalletBarcode == dto.PalletBarcode);
            if (sobj != null)
            {
                message = "编码已存在！";
                return false;
            }
            _pallrepository.AddEntity(dto);
            return _unitOfWork.SaveChangesEntity();
        }

        public bool AddPalletList(BatchPalletDTO m, out string message)
        {
            message = string.Empty;
            string name = m.Type.GetDescription();
            var beginBarCodeInt = GetPalletCodeInt(m.BeginBarcode,m.Type,out message);
            if (beginBarCodeInt == 0)
            {
                return false;
            }
            _unitOfWork.BeginTransaction();
            try
            {
                var existingOrderIds = _pallrepository.GetEntityAlls().Select(x => x.PalletBarcode).ToList();
                for (int i = 0; i < m.Num; i++)
                {
                    var nextBarCode = (beginBarCodeInt+i).ToString();
                    if (nextBarCode.Length > 4)
                    {
                        message = "生成失败,本次生成会有条码超过四位数";
                        return false;
                    }
                    Pallet p = new Pallet();
                    p.Id = YitIdHelper.NextId();
                    p.PalletName = name + nextBarCode;
                    p.PalletBarcode = nextBarCode;
                    p.Type = m.Type;
                    p.Opprint = m.IsPrint;
                    p.CreateDate = DateTime.Now;
                    p.Status = 1;
                    if (existingOrderIds.Contains(p.PalletBarcode))
                    {
                        message += "托盘条码" + p.PalletBarcode + "已存在";
                        continue;
                    }
                    _pallrepository.AddEntity(p);
                }
                if(_unitOfWork.SaveChangesEntity())
                {
                    _unitOfWork.CommitChanges();
                    return true;
                }
                _unitOfWork.RollbackChanges();
                return false;
            }
            catch (Exception ex)
            {
                message = ex.Message;
                _unitOfWork.RollbackChanges();
                return false;
                throw;
            }
        }

        public bool DelPallet(long id)
        {
            var del = _pallrepository.QueryEntityById(id);
            if (del != null)
            {
                _pallrepository.DelEntity(del);
                return _unitOfWork.SaveChangesEntity();
            }
            return false;
        }

        public Pallet? GetPalletByid(long id)
        {
            return _pallrepository.QueryEntityById(id);
        }

        public List<Pallet> GetPallets(string? name, int type, long incell, int pageIndex, int pageSize, out int totalCount)
        {
            var list = _pallrepository.GetEntityAlls();
            if (!string.IsNullOrEmpty(name))
            {
                list = list.Where(x => x.PalletName.Contains(name));
            }
            if (incell > 0)
            {
                if (incell == 1)
                {
                    list = list.Where(x => x.LocationCode == null);
                }
                if (incell == 2)
                {
                    list = list.Where(x => x.LocationCode != null);
                }
            }

            if (type != -1)
            {
                list = list.Where(x => x.Type == (EmPalletType)type);
            }
            totalCount = list.Count();
            var lists = _pallrepository.GetEntityAlls(list, pageIndex, pageSize, out totalCount, x => x.CreateDate, false);
            return lists.ToList();
        }

        public List<Pallet> GetTypePallet(EmPalletType palletType)
        {
            return _pallrepository.GetEntityWhereAll(p => p.Type == palletType).ToList();
        }

        public bool PalletVerify(string PalletCode, out string message)
        {
            message = string.Empty;
            var pallet = _pallrepository.QueryIsEntityWhere(p => p.PalletBarcode == PalletCode);
            if (pallet == null || pallet.Status==0) 
            {
                message = "托盘不存在或已被禁用！";
                return false;
            }
            //var sobj = _stackingstoragerepository.QueryIsEntityWhere(x => x.PalletBarcode == PalletCode);
            //if (sobj != null)
            //{
            //    message = "托盘正在作业中";
            //    return false;
            //}
            //var putobj = _putawayorderrepository.QueryIsEntityWhere(x => x.PalletBarcode == PalletCode && x.Status == 4 && x.BillType == 1 && x.SourceType == 1);
            //if(putobj!=null)
            //{
            //    message = "当前托盘正在作业中！";
            //    return false;
            //}
            var inventory = _inventoryrepository.QueryIsEntityWhere(r => r.PalletBarcode == PalletCode && r.Status==1);
            if (inventory is not null)
            {
                message = "当前托盘已在库存中！";
                return false;
            }
            return true;
        }

        public bool UpdPallet(Pallet dto, out string message)
        {
            message = "";
            var list = _pallrepository.QueryIsEntityWhere(x => x.Id != dto.Id && x.PalletBarcode == dto.PalletBarcode);

            if (list != null)
            {
                message = "编码已存在！";
                return false;
            }
            _pallrepository.UpdEntity(dto);
            return _unitOfWork.SaveChangesEntity();
        }
    }
}
